#include "thread_wrap.h"

#include <thread>
#include <mutex>
#include <string>

#include "thread_task.h"

namespace thread {

class TPThread::Impl {
 public:
  Impl(std::weak_ptr<ThreadPool> &&thread_pool,
       std::chrono::seconds &&wait_second)
      : thread_pool_(thread_pool), wait_second_(wait_second) {}

  ~Impl() = default;

  std::unique_ptr<std::thread> handle_{nullptr};       // 线程句柄
  std::weak_ptr<ThreadPool> thread_pool_;              // 所属线程池
  std::shared_ptr<ThreadTask> current_task_{nullptr};  // 当前任务
  size_t id_{0};                                       // 线程id
  std::string name_{""};                               // 线程名称
  std::chrono::seconds wait_second_{
      std::chrono::seconds(-1)};  // 空闲等待时间 小于0为永久线程
  uint32_t done_tasks_{
      0};  // 线程启动在未改变位闲置状态下连续执行任务的任务计数
  State state_{State::kStateSleep};  // 线程状态
  std::mutex mutex_{};               // 互斥锁
};

TPThread::TPThread(std::weak_ptr<ThreadPool> &&thread_pool,
                   std::chrono::seconds wait_second) {
  impl_ = std::make_unique<TPThread::Impl>(std::move(thread_pool),
                                           std::move(wait_second));
}

TPThread::~TPThread() {}

void TPThread::Create(std::string prefix) {
  impl_->handle_ = std::make_unique<std::thread>(&TPThread::ThreadFunc);
  impl_->id_     = static_cast<size_t>(
      std::hash<std::thread::id>()(impl_->handle_->get_id()));
  impl_->name_ = prefix + std::to_string(impl_->id_);
}

void TPThread::ThreadFunc() { 
  
}

void TPThread::OnStart() {}

void TPThread::OnEnd() {}

void TPThread::OnProcessTaskStart(ThreadTask *task) {}

void TPThread::ProcessTask(ThreadTask *task) { task->Process(); }

void TPThread::OnProcessTaskEnd(ThreadTask *task) {}

size_t TPThread::GetThreadId() const { return impl_->id_; }

std::string_view TPThread::GetThreadName() const {
  return std::string_view(impl_->name_.data(), impl_->name_.size());
}

thread::TPThread::TPThread::State TPThread::GetState() const {
  return impl_->state_;
}

void TPThread::Join() {
  if (impl_->handle_) {
    impl_->handle_->join();
  }
}

void TPThread::Detach() {
  if (impl_->handle_) {
    impl_->handle_->detach();
  }
}

thread::ThreadTask *TPThread::GetNextTask() {}

thread::ThreadTask *TPThread::GetCurrentTask() const {
  return impl_->current_task_.get();
}

void TPThread::SetCurrentTask(ThreadTask *task) {
  impl_->current_task_ = std::make_shared<ThreadTask>(task);
}

ThreadPool *TPThread::GetThreadPool() const {
  if (auto tp = impl_->thread_pool_.lock()) {
    return tp.get();
  }

  return nullptr;
}

void TPThread::ResetTaskCounter() { impl_->done_tasks_ = 0; }

void TPThread::IncTaskCounter() { ++(impl_->done_tasks_); }

std::string TPThread::PrintState() {
  std::lock_guard<std::mutex> lock(impl_->mutex_);
  char buf[128];
  sprintf(buf, "%p,%u", impl_->current_task_.get(), impl_->done_tasks_);
  return buf;
}

}  // namespace thread